package com.testpro.EasyUseCase.Core.imp;

import com.testpro.EasyUseCase.Bean.UseCase;
import com.testpro.EasyUseCase.Bean.UseCaseDG;
import com.testpro.EasyUseCase.Core.Abstract.AbstractConvert;
import com.testpro.EasyUseCase.Swing.CreateUi;
import com.testpro.easyrest.Util.ExcelUtil;
import lombok.extern.slf4j.Slf4j;
import org.xmind.core.INotes;
import org.xmind.core.IPlainNotesContent;
import org.xmind.core.ITopic;
import org.xmind.core.ITopicPath;
import org.xmind.core.marker.IMarkerRef;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;

@Slf4j
public class XMindUseCase extends AbstractConvert<UseCase> {
  private Integer setUps = 1;

  @Override
  protected void writeExcelDG(
      LinkedList<UseCase> listUseCase, String outPutExcelFilePath, Class<UseCase> useCaseClass)
      throws FileNotFoundException {
    if (System.getProperty("DG") != null) {
      Map<String, UseCaseDG> map = new LinkedHashMap<>();

      final String dg = System.getProperty("DG");
      if (dg.equals("true")) {
        List<UseCaseDG> list = new LinkedList<>();
        listUseCase.forEach(
            a -> {
              UseCaseDG caseDG = new UseCaseDG();
              caseDG.setBigModular(a.getModular());
              final String[] caseName = a.getCaseName().split("-");
              caseDG.setModular(caseName[0]);
              caseDG.setTestName(caseName[1]);
              final String key =
                  caseDG.getBigModular() + caseDG.getModular() + caseDG.getTestName();

              if (map.get(key) != null) {
                UseCaseDG useCaseDG = map.get(key);
                useCaseDG.setExpectedResults(
                    useCaseDG.getExpectedResults() + "\n" + a.getExpectedResults());
                map.put(key, useCaseDG);

              } else {
                caseDG.setExpectedResults(a.getExpectedResults());
                map.put(key, caseDG);
              }
            });
        final Collection<UseCaseDG> values = map.values();
        for (UseCaseDG useCaseDG : values) {
          list.add(useCaseDG);
        }

        if (System.getProperty("os.name").equals("Windows")) {
        outPutExcelFilePath = new File(outPutExcelFilePath).getParent() + "\\" + "大纲.xlsx";
        new ExcelUtil()
            .WriterExcelWithListBean(new File(outPutExcelFilePath), list, UseCaseDG.class, 1, 0, 1);
        }else{
          outPutExcelFilePath = String.format("%s/大纲.xlsx", new File(outPutExcelFilePath).getParent());
          new ExcelUtil()
                  .WriterExcelWithListBean(new File(outPutExcelFilePath), list, UseCaseDG.class, 1, 0, 1);
        }
      }
    }
  }

  /**
   * @param linkedITopicList 用例对象集合
   * @return LinkedList<UseCase> 返回用例目标对象集合
   */
  protected LinkedList<UseCase> analysis(LinkedList<ITopic> linkedITopicList) {

    LinkedList<UseCase> useCases = new LinkedList<>();

    ITopic first = linkedITopicList.getFirst();
    LinkedList<ITopic> allParentList = getAllParentList(first);
    for (ITopic iTopic : allParentList) {
      if (iTopic.isRoot()) {
        setOutputPathByVersionInfo(iTopic);
        break;
      }
    }

    for (ITopic topic : linkedITopicList) {
      UseCase useCase = toUseCaseFromPathInfo(topic);
      if (useCase != null) {
        useCases.add(useCase);
      }
    }
    return useCases;
  }

  /** @param topic 根据topic信息进行排查 判断是否存在version信息， 如果存在信息即改变最终的文件路径。 */
  private void setOutputPathByVersionInfo(ITopic topic) {
    // 获取脑图的标签 整合到OutPutExcelFilePath中生成的文件就带版本信息
    Set<String> labels = topic.getLabels();
    if (labels.size() == 1) {
      Iterator<String> iterator = labels.iterator();
      String next = iterator.next();
      File file_dir = new File(this.getOutPutExcelFilePath());
      String name = file_dir.getName();
      String path = file_dir.getParent();
      String[] splitFilename = name.split("\\.");
      if (splitFilename.length == 2) {
        String outputExcelFilepath =
            path + "\\" + splitFilename[0] + "-" + next + "." + splitFilename[1];
        this.setOutPutExcelFilePath(outputExcelFilepath);
        log.info("已检测到您的Root含有标签,道路千万条，文件名称合法就一条 不能有特殊字符！！已为您将输入文件路径转至{}路径", outputExcelFilepath);
      }
    }
  }

  /**
   * 根据路径信息返回信息集合
   *
   * @param topic xmind用例对象
   * @return 用例的Path路径
   */
  private LinkedList<String> topicPathInfo(ITopic topic) {
    LinkedList<String> linkedList = new LinkedList<>();
    ITopicPath path = topic.getPath();
    List<ITopic> iTopics = path.toTopicList();
    for (ITopic topic1 : iTopics) {
      linkedList.add(topic1.getTitleText());
    }
    return linkedList;
  }

  private UseCase toUseCaseFromPathInfo(ITopic topic) {
    LinkedList<String> PathInfo = this.topicPathInfo(topic);
    String Test_NO = System.getProperty(CreateUi.SYSTEM_TEST_NO);
    UseCase useCase = new UseCase();

    String markInfo = getPriorityInfo(topic); // 获取当前用例的优先级信息
    useCase.setMarker(markInfo);

    String CaseStatus = getUseCaseStatus(topic); // 获取用例状态
    useCase.setCheckResult(CaseStatus);

    String ReMarks = getUseCaseReMarks(topic); // 获取用例用例的备注信息
    useCase.setReMarks(ReMarks);
    if (Test_NO != null) {
      useCase.setCaseNo(Test_NO + "-" + setUps);
    } else {
      useCase.setCaseNo(String.valueOf(setUps));
    }
    useCase.setSetups(String.valueOf(setUps));
    if (PathInfo.size() <= 4) {
      return null;
    } else {
      useCase.setModular(PathInfo.get(1)); // 设置模块
      useCase.setCaseName(PathInfo.get(2) + "-" + PathInfo.get(3)); // 设置用例名称
      useCase.setCaseObjective("验证功能是否正确实现");
      if (PathInfo.size() >= 6) {
        if (PathInfo.get(4).equals("前置条件")) {
          // 设置前置条件
          useCase.setPrecondition(PathInfo.get(5));
          if (PathInfo.size() >= 7) {
            if (PathInfo.size() == 7) {
              useCase.setSteps(PathInfo.get(6));
              // 设置步骤信息
            } else {
              List<String> linkedList = new LinkedList<>();
              for (int i = 6; i < PathInfo.size(); i++) {
                if (i == PathInfo.size() - 1) {
                  useCase.setExpectedResults(PathInfo.get(i));
                  // 设置预期结果
                } else {
                  // 收集步骤信息
                  linkedList.add(PathInfo.get(i));
                }
              }
              // 设置步骤信息
              String UseCaseStep = UseCaseStepInfo(linkedList);
              useCase.setSteps(UseCaseStep);
            }
          }
        } else {
          useCase.setPrecondition("无");
          List<String> linkedList = new LinkedList<>();

          for (int i = 4; i < PathInfo.size(); i++) {
            if (i == PathInfo.size() - 1) {
              useCase.setExpectedResults(PathInfo.get(i));
              // 设置预期结果
            } else {
              // 收集步骤信息
              linkedList.add(PathInfo.get(i));
            }
          }
          // 设置步骤信息
          String UseCaseSetp = UseCaseStepInfo(linkedList);
          useCase.setSteps(UseCaseSetp);
        }
      }
    }
    setUps = setUps + 1;
    return useCase;
  }

  /**
   * @param topic 用例对象
   * @return 用例的备注信息
   */
  private String getUseCaseReMarks(ITopic topic) {
    String ReMarks = null;
    LinkedList<ITopic> parentlist = getAllParentList(topic);

    for (ITopic iTopic : parentlist) {
      if (ReMarks != null) {
        break;
      }
      ReMarks = getReMarksInfo(iTopic);
    }
    return ReMarks;
  }

  /**
   * 根据用例信息 获取备注信息
   *
   * @param iTopic 用例对象
   * @return 用例的备注信息
   */
  static String getReMarksInfo(ITopic iTopic) {
    String reMarks = null;
    INotes notes = iTopic.getNotes();
    if (notes != null) {
      IPlainNotesContent plain = (IPlainNotesContent) notes.getContent(INotes.PLAIN);
      if (plain != null) {
        reMarks = plain.getTextContent();
      }
    }
    return reMarks;
  }

  /**
   * @param topic 用例对象
   * @return 用例状态
   */
  private String getUseCaseStatus(ITopic topic) {
    String UseCaseStatus = null;

    LinkedList<ITopic> parentList = getAllParentList(topic);

    for (ITopic iTopic : parentList) {
      if (UseCaseStatus != null) {
        break;
      }

      for (IMarkerRef next : iTopic.getMarkerRefs()) {
        String markerId = next.getMarkerId();

        if (markerId.equals("symbol-right")) {
          UseCaseStatus = "已通过";
        }
        if (markerId.equals("symbol-wrong")) {
          UseCaseStatus = "未通过";
        }
      }
    }

    return UseCaseStatus;
  }

  /**
   * @param topic 用例对象
   * @return 获取所有用例的父亲对象
   */
  private LinkedList<ITopic> getAllParentList(ITopic topic) {
    LinkedList<ITopic> parentlist = new LinkedList<>();
    parentlist.add(topic);
    while (topic.getParent() != null) {
      topic = topic.getParent();
      parentlist.add(topic);
    }
    return parentlist;
  }

  /**
   * 根据最子节点获取标注数字决定用例等级
   *
   * @param topic 用例对象
   * @return 用例优先级
   */
  private String getPriorityInfo(ITopic topic) {
    String MarkInfo = null;
    LinkedList<ITopic> parentList = getAllParentList(topic);

    for (ITopic iTopic : parentList) {
      if (MarkInfo != null) {
        break;
      }
      for (IMarkerRef next : iTopic.getMarkerRefs()) {
        String markerId = next.getMarkerId();
        String[] split = markerId.split("-");
        if (split.length == 2 && split[0].equals("priority")) {
          MarkInfo = split[1];
        }
      }
    }

    if (MarkInfo == null) {
      MarkInfo = "-1";
    }
    switch (MarkInfo) {
      case "1":
        MarkInfo = "优先级-1";
        break;
      case "2":
        MarkInfo = "优先级-2";
        break;

      case "3":
        MarkInfo = "优先级-3";
        break;

      case "4":
        MarkInfo = "优先级-4";
        break;

      case "5":
        MarkInfo = "优先级-5";
        break;

      case "6":
        MarkInfo = "优先级-6";
        break;

      case "7":
        MarkInfo = "优先级-7";
        break;

      case "8":
        MarkInfo = "优先级-8";
        break;

      case "9":
        MarkInfo = "优先级-9";
        break;

      default:
        MarkInfo = "无";
    }
    return MarkInfo;
  }

  private String UseCaseStepInfo(List<String> list) {
    StringBuilder buffer = new StringBuilder();
    for (int i = 0; i < list.size(); i++) {
      if (i == list.size() - 1) {
        buffer.append(i + 1).append(".").append(list.get(i)).append("。");
      } else {
        buffer.append(i + 1).append(".").append(list.get(i)).append("。").append("\n");
      }
    }
    return buffer.toString();
  }
}
